package org.eiahe.hr.salary.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ehe.common.core.exception.BusinessException;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.system.domain.vo.SysDeptVo;
import org.ehe.system.service.ISysDeptService;
import org.eiahe.hr.salary.domain.SalaryStatistics;
import org.eiahe.hr.salary.domain.bo.SalaryStatisticsBo;
import org.eiahe.hr.salary.domain.dto.SalaryGenerateStatDto;
import org.eiahe.hr.salary.domain.vo.SalaryStatisticsVo;
import org.eiahe.hr.salary.mapper.SalaryStatisticsMapper;
import org.eiahe.hr.salary.mapper.SalaryStructureMapper;
import org.eiahe.hr.salary.domain.SalaryStructure;
import org.eiahe.hr.salary.service.ISalaryStatisticsService;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * 薪资统计Service业务层处理
 *
 * @author zhangnn
 */
@RequiredArgsConstructor
@Service
public class SalaryStatisticsServiceImpl implements ISalaryStatisticsService {

    private final SalaryStatisticsMapper baseMapper;
    private final SalaryStructureMapper salaryStructureMapper;
    private final ISysDeptService deptService;

    @Override
    public SalaryStatisticsVo queryById(Long statisticsId) {
        SalaryStatisticsVo salaryStatisticsVo = baseMapper.selectVoById(statisticsId);
        if(null != salaryStatisticsVo.getDepartment()){
            SysDeptVo sysDeptVo = deptService.selectDeptById(salaryStatisticsVo.getDepartment());
            if(Objects.nonNull(sysDeptVo)){
                salaryStatisticsVo.setDepartmentName(sysDeptVo.getDeptName());
            }
        }
        return salaryStatisticsVo;
    }

    @Override
    public List<SalaryStatisticsVo> queryList(SalaryStatisticsBo bo) {
        LambdaQueryWrapper<SalaryStatistics> lqw = buildQueryWrapper(bo);
        List<SalaryStatisticsVo> salaryStatisticsVos = baseMapper.selectVoList(lqw);
        salaryStatisticsVos.forEach(s->{
            if(null != s.getDepartment()){
                SysDeptVo sysDeptVo = deptService.selectDeptById(s.getDepartment());
                if(Objects.nonNull(sysDeptVo)){
                    s.setDepartmentName(sysDeptVo.getDeptName());
                }
            }
        });
        return salaryStatisticsVos;
    }

    @Override
    public TableDataInfo<SalaryStatisticsVo> queryPageList(SalaryStatisticsBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<SalaryStatistics> lqw = buildQueryWrapper(bo);
        IPage<SalaryStatisticsVo> page = baseMapper.selectVoPage(pageQuery.build(), lqw);

        page.getRecords().forEach(s->{
            if(null != s.getDepartment()){
                SysDeptVo sysDeptVo = deptService.selectDeptById(s.getDepartment());
                if(Objects.nonNull(sysDeptVo)){
                    s.setDepartmentName(sysDeptVo.getDeptName());
                }
            }
        });

        return TableDataInfo.build(page);
    }

    /**
     * 构建查询条件
     *
     * @param bo 薪资统计业务对象
     * @return 查询条件
     */
    private LambdaQueryWrapper<SalaryStatistics> buildQueryWrapper(SalaryStatisticsBo bo) {
        LambdaQueryWrapper<SalaryStatistics> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getYearMonth()), SalaryStatistics::getYearMonth, bo.getYearMonth());
        lqw.eq(StringUtils.isNotBlank(bo.getDepartment()), SalaryStatistics::getDepartment, bo.getDepartment());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SalaryStatistics::getStatus, bo.getStatus());
        lqw.orderByDesc(SalaryStatistics::getCreateTime);
        return lqw;
    }

    @Override
    public Boolean insertByBo(SalaryStatisticsBo bo) {
        SalaryStatistics add = MapstructUtils.convert(bo, SalaryStatistics.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setStatisticsId(add.getStatisticsId());
        }
        return flag;
    }

    @Override
    public Boolean updateByBo(SalaryStatisticsBo bo) {
        SalaryStatistics update = MapstructUtils.convert(bo, SalaryStatistics.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(SalaryStatistics entity) {
        // TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public Boolean generateStatistics(SalaryGenerateStatDto dto) {
        try {
            for (Long departmentId : dto.getDepartmentIds()) {
                String department = String.valueOf(departmentId);
                String yearMonth = dto.getYearMonth();

                // 构建查询条件
                LambdaQueryWrapper<SalaryStructure> queryWrapper = Wrappers.lambdaQuery();
                queryWrapper.eq(SalaryStructure::getYearMonth, yearMonth);
                if (StringUtils.isNotBlank(department)) {
                    queryWrapper.eq(SalaryStructure::getDepartment, department);
                }
                queryWrapper.eq(SalaryStructure::getStatus, "0"); // 只统计正常状态的数据

                // 查询薪资数据
                List<SalaryStructure> salaryList = salaryStructureMapper.selectList(queryWrapper);

                if (CollectionUtils.isNotEmpty(salaryList)) {
                    // 计算统计信息
                    SalaryStatistics statistics = new SalaryStatistics();
                    statistics.setYearMonth(yearMonth);
                    statistics.setDepartment(department);
                    statistics.setEmployeeCount(salaryList.size());

                    // 计算各项总额
                    BigDecimal grossSalaryTotal = BigDecimal.ZERO;
                    BigDecimal netSalaryTotal = BigDecimal.ZERO;
                    BigDecimal socialInsurancePersonalTotal = BigDecimal.ZERO;
                    BigDecimal housingFundPersonalTotal = BigDecimal.ZERO;
                    BigDecimal personalTaxTotal = BigDecimal.ZERO;
                    BigDecimal maxGrossSalary = BigDecimal.ZERO;
                    BigDecimal minGrossSalary = salaryList.get(0).getGrossSalary();

                    for (SalaryStructure salary : salaryList) {
                        grossSalaryTotal = grossSalaryTotal.add(salary.getGrossSalary());
                        netSalaryTotal = netSalaryTotal.add(salary.getNetSalary());
                        socialInsurancePersonalTotal = socialInsurancePersonalTotal.add(salary.getSocialInsurancePersonal());
                        housingFundPersonalTotal = housingFundPersonalTotal.add(salary.getHousingFundPersonal());
                        personalTaxTotal = personalTaxTotal.add(salary.getPersonalTax());

                        // 计算最高和最低应发工资
                        if (salary.getGrossSalary().compareTo(maxGrossSalary) > 0) {
                            maxGrossSalary = salary.getGrossSalary();
                        }
                        if (salary.getGrossSalary().compareTo(minGrossSalary) < 0) {
                            minGrossSalary = salary.getGrossSalary();
                        }
                    }

                    // 设置统计值
                    statistics.setGrossSalaryTotal(grossSalaryTotal);
                    statistics.setNetSalaryTotal(netSalaryTotal);
                    statistics.setSocialInsurancePersonalTotal(socialInsurancePersonalTotal);
                    statistics.setHousingFundPersonalTotal(housingFundPersonalTotal);
                    statistics.setPersonalTaxTotal(personalTaxTotal);
                    statistics.setMaxGrossSalary(maxGrossSalary);
                    statistics.setMinGrossSalary(minGrossSalary);

                    // 计算平均值
                    if (salaryList.size() > 0) {
                        statistics.setAvgGrossSalary(
                            grossSalaryTotal.divide(new BigDecimal(salaryList.size()), 2, BigDecimal.ROUND_HALF_UP));
                        statistics.setAvgNetSalary(
                            netSalaryTotal.divide(new BigDecimal(salaryList.size()), 2, BigDecimal.ROUND_HALF_UP));
                    }

                    statistics.setStatus("0"); // 正常状态

                    // 检查是否已存在相同年月和部门的统计记录
                    LambdaQueryWrapper<SalaryStatistics> existQuery = Wrappers.lambdaQuery();
                    existQuery.eq(SalaryStatistics::getYearMonth, yearMonth);
                    if (StringUtils.isNotBlank(department)) {
                        existQuery.eq(SalaryStatistics::getDepartment, department);
                    } else {
                        existQuery.isNull(SalaryStatistics::getDepartment);
                    }

                    SalaryStatistics existing = baseMapper.selectOne(existQuery);
                    if (existing != null) {
                        // 更新现有记录
                        statistics.setStatisticsId(existing.getStatisticsId());
                        baseMapper.updateById(statistics);
                    } else {
                        // 插入新记录
                        baseMapper.insert(statistics);
                    }
                }
            }
            return true;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            return false;
        }
    }
}
